<template>
	<div class="chatAppBody">
		<div class="chatTitle">chatGPT</div>
		<div class="chatBox">
			<div v-for="row in msgList">
				<div v-if="row.isme!=true">
					<div class="chatNotice">{{row.time}}</div>
					<div class="chatRow">
						<el-avatar class="chatAvatar" :size="30" :src="row.avator"></el-avatar>
						<div class="chatMsgContent">
							<div class="chatUsername">{{row.name}}</div>
							<div class="chatContent">
								<div v-html="html(row.content)"></div>
							</div>
						</div>
					</div>
				</div>
				<div v-if="row.isme==true">
					<div class="chatNotice" v-if="row.show_time==true">{{row.time}}</div>
					<div class="chatRow chatRowMe">
						<div class="chatContent">{{row.content}}</div>
					</div>
				</div>
			</div>
		</div>
		<div class="chatBottom">
			<div class="chatAreaBox">
				<div class="chatArea">
					<textarea class="chatAreaInput" v-model="originMessage"  @keyup.ctrl.enter.exact="chatToUser($event)" @keyup.enter.exact="chatToUser($event,'enter')" ></textarea>
					<div @click="chatToUser($event)" class="chatSendBtn iconfont icon-fasong"></div>
				</div>
			</div>

			<div class="chatCopyright">
				<i class="el-icon-chat-dot-round"></i> Powered by <a href='https://gofly.v1kf.com' target="_blank">唯一客服</a>
			</div>
		</div>
		
		<audio id="chatMessageAudio" style="display: none;" :src="require('@/assets/alert2.ogg')"></audio>
	</div>
</template>

<script>
	import tools from '../tools/functions.js'
	import storage from '../tools/localStorage.js'
	import xss from 'xss'
	import Api2d from 'api2d'
	import MarkdownIt from 'markdown-it';
	import hljs from 'highlight.js';
	import 'highlight.js/styles/monokai-sublime.css';
	export default {
	  name: 'ChatApp',
		data() {
		  return {
			  window:window,
			  secret:"",
			  message:[{
						"role": "system", 
						"content": "你是唯一客服系统的小助手，你的名字叫唯一精灵，最擅长程序开发了"
						}],
			  originMessage:"",
			  msgList:[],
			  sendDisable:false,
		  }
		},
		methods: {
		   //发送给客户
			chatToUser:function(e) {
				let _this=this;
				this.secret=tools.getQuery("secret");
				if(!this.secret){
					_this.$message({
					  message: "请在GET参数secret中提供chatGPT密钥",
					  type: 'error'
					});
					return;
				};
				if(this.sendDisable) return;
				//用户点击了ctrl+enter触发
				if(e && e.ctrlKey && e.keyCode==13) { 
					this.originMessage += '\n';
					return;
				}
				if(this.originMessage=="") return;
				_this.message.push({
					"role": "user", 
					"content": this.originMessage
					});
				let sendMessage = {
					"messages": _this.message,
					"model": "gpt-3.5-turbo",
					"stream":true,
				};
				let showMessage={
					isme:true,
					content:this.originMessage,
					show_time:false,
				}
				this.msgList.push(showMessage);
				this.scrollBottom();
				let headers={
					headers:{ 
						'Authorization': `Bearer ${this.secret}`,
						},
					responseType: 'stream',
				}
				this.sendDisable=true;
				
			
				const timeout = 1000*20; // 60秒超时
				const api = new Api2d(this.secret, "https://api.openai.com", timeout);
				// chat 补全
				let i=0;
				const ret = api.completion({
					model:'gpt-3.5-turbo',
					messages: _this.message,
					stream: true, // 支持 stream，注意stream为 true 的时候，返回值为undefined
					onMessage: (string)=> {
						console.log( "SSE返回:", string );
						if(i==0){
							let showMessage={
								isme:false,
								avator:"https://goflychat.oss-cn-hangzhou.aliyuncs.com/static/upload/avator/2022June/32a988a3c2f8700119fa1f5da1b6a4bd.png",
								content:"",
								time:tools.shortTime(tools.getNowDate())
								}
							_this.msgList.push(showMessage);
						}else{
							_this.msgList[_this.msgList.length-1].content=string;
							_this.scrollBottom();
						}
						i++;
						
					},
					onEnd: (string)=> {
						console.log( "end", string );
						_this.sendDisable=false;
						_this.originMessage=""
						string=tools.trim(string,"\n");
						_this.message.push({
							"role": "assistant", 
							"content": string
							});
						_this.alertSound();
						_this.scrollBottom();
					}
				});
				ret.catch(function(error) {
				  console.log(error);
				  _this.$message({
				    message:error,
				    type: 'error'
				  });
				  _this.sendDisable=false;
				});
				
			},
			//滚动到底部
			scrollBottom:function(){
				var _this=this;
				this.$nextTick(function(){
					var container = _this.$el.querySelector(".chatBox");
					container.scrollTop = 999999999;
				});
			},
			//提醒声音
			alertSound(){
				tools.alertSound("chatMessageAudio","");
			},
			 html(sourceStr) {
			      const md = new MarkdownIt({
			        highlight: function (str, lang) {
			          if (lang && hljs.getLanguage(lang)) {
			            try {
			              return '<pre class="hljs"><code>' +
			                     hljs.highlight(lang, str, true).value +
			                     '</code></pre>';
			            } catch (__) {}
			          }
			
			          return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + '</code></pre>';
			        }
			      });
			
			      return md.render(sourceStr);
			}
		},
		mounted: function () {
		}
	}
</script>

<style lang="scss">
	.chatAppBody{
		display: flex;
		flex-direction: column;
		height: 100vh;
		background-color: #f1f5f8;
	}
	.chatTitle{
		background: #fff;
		padding: 5px 0px;
		text-align: center;
		font-size: 14px;
	}
	.chatBox{
		flex: 1;
		padding: 0px 5px;
		padding-bottom: 15px;
		overflow: auto;
	}
	.chatBottom{
		display: flex;
		flex-direction: column;
	}
	.chatRow{
		display: flex;
		align-items: flex-end;
		margin: 5px 0px;
	}
	.chatAvatar{
		margin-right: 5px;
		flex-shrink: 0;
	}
	.chatUsername {
	    font-size: 12px;
	    white-space: nowrap;
	    color: #999;
	    margin-bottom: 2px;
	}
	.chatContent{
		border-radius: 10px 10px 10px 0px;
		padding: 10px;
		background-color: rgb(255,255,255);
		box-shadow: 0 5px 30px rgb(50 50 93 / 8%), 0 1px 3px rgb(0 0 0 / 5%);
		font-size: 14px;
		word-break: break-all;
		line-height: 21px;
		display: inline-block;
	}
	
	.chatRowMe{
		justify-content: flex-end;
	}
	.chatRowMe .chatContent{
		border-radius: 10px 10px 0px 10px;
	}
	.chatNotice{
		text-align: center;
		color: #bbb;
		margin: 8px 0;
		font-size: 12px;
	}
	.chatAreaBox{
		margin: 0px 10px;
		margin-bottom: 10px;
		box-shadow: 0 5px 30px rgb(50 50 93 / 8%), 0 1px 3px rgb(0 0 0 / 5%);
		border-radius: 10px;
	}
	.chatArea{
		display: flex;
		padding: 3px 5px;
		align-items: center;
		background: #fff;
		border-radius: 10px;
	}
	.chatArea .iconfont{
		color: #383838;
		font-size: 18px;
		margin: 0px 6px;
		cursor: pointer;
	}
	.chatArea .iconfont:hover{
		color: #409eff;
	}
	.chatAreaInput{
		border-radius: 10px;
		border: 0;
		flex: 1;
		outline: none;
		resize: none;
		box-sizing: border-box;
		color: #505050;
		min-height: 50px;
		font-size: 16px;
	}
	.chatCopyright{
		color: #999a9b;
		font-size: 12px;
		text-align: center;
		margin-bottom: 10px;
		filter: grayscale(1);
		opacity: .9;
		font-family: Inter,-apple-system,system-ui,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Tahoma,Arial,sans-serif;
	}
	
	.chatContent a{
		color: #07a9fe;
		text-decoration: none;
	}
	.chatContent pre{
		padding: 10px;
		margin: 10px 0px;
	}
	.alink{
		display: inline-block;
		word-break: break-all;
		color: #07a9fe;
		font-size: 12px;
		cursor: pointer;
	}
	
	</style>